
from rest_framework import serializers  #导入序列化器
#序列化器对json和模型对象进行互相转化，以及校验数据
#序列化器里的字段名一定是模型字段里有的，可以少不可以多，少了的不会显示
#序列化器会给我们生成一个可以操作的页面，label为其中字段名,在前端页面中展示
from .models import Student,Classes

#如果是订单这种字段很复杂的就用这种，自己写创建，修改，删除
# class StudentSerializer(serializers.Serializer):
#     id = serializers.CharField(label='ID字段',read_only=True)
#     name = serializers.CharField(max_length=30,label='姓名')
#     # required=False表示可不传
#     age = serializers.IntegerField(label='年龄',required=False)
#     sex = serializers.IntegerField(label='性别',required=False)
#     create_time = serializers.DateTimeField(required=False,label='创建时间')
#     update_time = serializers.DateTimeField(required=False,label='更新时间')
#     is_delete = serializers.BooleanField(default=False,label='逻辑删除',required=False)
#
#     def create(self, validated_data):
#         #数据的创建
#         #因为传入数据格式为{'name':'shduw','age':'12'}这种格式，所以要把字典解包
#         return Student.objects.create(**validated_data) #元组解包： * + 元组名。  字典解包：** + 字典名
#
#     def update(self, instance, validated_data):  #instance是原本的数据，validated_data是传入的数据
#         #数据的修改
#         instance.name = validated_data.get('name',instance.name) #表示如果有传入的数据就用name，没传入的话就用原来的数据(instance.name)
#         instance.age = validated_data.get('age',instance.age)
#         instance.sex = validated_data.get('sex',instance.sex)
#         instance.save()
#         return instance


#这种会自动生成create和update，标准增删改查，字段较少可以用， ModelSerializer也是serializer的子集 （优化）
class StudentSerializer(serializers.ModelSerializer):
    # 重写，默认展示为 classes=classes.id 变成classes=class.__str__()   要写在学生里面，关联对象里
    # classes = serializers.StringRelatedField(label='班级') #但会根据班级id来选择，会导致无法继续添加，一般不用此方法
    class_name = serializers.CharField(source='classes.name',read_only=True)#新增一个字段，并正向访问引入模型对象外键里的name(classes.name)，read_only表示只读

    class Meta:
        model = Student  #你要做哪一个模型的序列化器就直接 model=那个模型
        # fields = '__all__'  #指定映射的字段，表示展示全部数据__all__指定全部的字段
        exclude = ['is_delete']  #不想展示渲染的字段，这个和展示全部数据不能同时有
        extra_kwargs = {  #逻辑校验，过滤，需满足条件
            'age':{'min_value':0,'max_value':130} #表示只能写0-130岁
        }

    # def validate_name(self,value):  #对单条数据进行逻辑校验  增加和修改都会被限制，需要满足条件
    #     #追加额外的逻辑校验，属性级别的，对单个字段进行校验
    #     if 'mq' not in value.lower():  #如果增加或修改名字时，增加和修改值里面没有包含mq这两个字符，则抛出异常
    #         raise serializers.ValidationError('用户名需要包含mq')
    #     return value

    # def validate(self,data): #对多个字段进行逻辑校验
    #     #追加额外的逻辑校验-对象级别的，会把传入的所有数据都传入data data={'name':'sunxibin','age':19}这种
    #     if 'mq' not in data['name'].lower():  # 不加lower，则是大小写都可以
    #         raise serializers.ValidationError('用户名需要包含mq') #抛出异常
    #     elif data['age'] < 18:
    #         raise serializers.ValidationError('未成年禁止访问')
    #     return data

class StudentSerializerSimple(serializers.ModelSerializer):  #专门供嵌套使用的序列化器，就是在班级中不需要展示学生的全部信息，只需要展示一部分所以就再写此函数来定义
    class Meta:
        model = Student
        fields = ['id','name','age','sex']

class ClassSerializer(serializers.ModelSerializer):
    #嵌套序列化，对管理器进行操作
    student_set = StudentSerializerSimple(many=True,read_only=True)#反向访问，在班级中显示全部学生信息，直接把学生序列化器拿过来即可，只读

    class Meta:
        model = Classes
        # fields = '__all__'
        exclude = ['is_delete']



